]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
workspace: Fix tab navigation order
authorFlorian Müllner <fmuellner@gnome.org>
Sun, 20 Aug 2017 09:19:39 +0000 (11:19 +0200)
committerFlorian Müllner <fmuellner@gnome.org>
Wed, 4 Oct 2017 16:12:26 +0000 (18:12 +0200)
By default the focus chain uses the same order as the list returned
by clutter_actor_get_children(), which corresponds to the z-order.
This doesn't work well in the window picker, where clones follow
the stacking of windows to ensure a correct overview transition,
but previews are laid out purely based on space efficiency. As
a result, the order in which window previews are navigated when
tabbing around is essentially random. Fix this by providing a
focus chain implementation that is based on the visual layout
of the previews rather than the stacking.

https://bugzilla.gnome.org/show_bug.cgi?id=786546

js/ui/workspace.js

index 3d78601702462970850f8f831f61bfd60aedae63..a377649139161008e052025fd55a4a239065bcb4 100644 (file)
@@ -132,6 +132,7 @@ var WindowClone = new Lang.Class({
 
         this.actor._delegate = this;
 
+        this.slotId = 0;
         this._slot = [0, 0, 0, 0];
         this._dragSlot = [0, 0, 0, 0];
         this._stackAbove = null;
@@ -1068,6 +1069,22 @@ function rectEqual(one, two) {
             one.height == two.height);
 }
 
+const WorkspaceActor = new Lang.Class({
+    Name: 'WorkspaceActor',
+    Extends: St.Widget,
+
+    vfunc_get_focus_chain: function() {
+        return this.get_children().filter(c => c.visible).sort((a,b) => {
+            let cloneA = (a._delegate && a._delegate instanceof WindowClone) ? a._delegate: null;
+            let cloneB = (b._delegate && b._delegate instanceof WindowClone) ? b._delegate: null;
+            if (cloneA && cloneB)
+                return cloneA.slotId - cloneB.slotId;
+
+            return 0;
+        });
+    }
+});
+
 /**
  * @metaWorkspace: a #Meta.Workspace, or null
  */
@@ -1100,7 +1117,7 @@ var Workspace = new Lang.Class({
         // Without this the drop area will be overlapped.
         this._windowOverlaysGroup.set_size(0, 0);
 
-        this.actor = new St.Widget({ style_class: 'window-picker' });
+        this.actor = new WorkspaceActor({ style_class: 'window-picker' });
         if (monitorIndex != Main.layoutManager.primaryIndex)
             this.actor.add_style_class_name('external-monitor');
         this.actor.set_size(0, 0);